int libxl_confirm_device_model_startup(libxl_ctx *ctx,
libxl_device_model_starting *starting)
{
- int problem = libxl_wait_for_device_model(ctx, starting->domid, "running",
- libxl_spawn_check,
- starting->for_spawn);
- int detach = libxl_detach_device_model(ctx, starting);
+ int problem = libxl_wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
+ int detach;
+ if ( !problem )
+ problem = libxl_spawn_check(ctx, starting->for_spawn);
+ detach = libxl_detach_device_model(ctx, starting);
return problem ? problem : detach;
- return 0;
}
int libxl_wait_for_device_model(libxl_ctx *ctx,
uint32_t domid, char *state,
int (*check_callback)(libxl_ctx *ctx,
+ uint32_t domid,
+ const char *state,
void *userdata),
void *check_callback_userdata)
{
nfds = xs_fileno(xsh) + 1;
while (rc > 0 || (!rc && tv.tv_sec > 0)) {
p = xs_read(xsh, XBT_NULL, path, &len);
- if (p && (!state || !strcmp(state, p))) {
- free(p);
- xs_unwatch(xsh, path, path);
- xs_daemon_close(xsh);
- if (check_callback) {
- rc = check_callback(ctx, check_callback_userdata);
- if (rc) return rc;
- }
- return 0;
+ if ( NULL == p )
+ goto again;
+
+ if ( NULL != state && strcmp(p, state) )
+ goto again;
+
+ if ( NULL != check_callback ) {
+ rc = (*check_callback)(ctx, domid, p, check_callback_userdata);
+ if ( rc > 0 )
+ goto again;
}
+
free(p);
+ xs_unwatch(xsh, path, path);
+ xs_daemon_close(xsh);
+ return rc;
again:
+ free(p);
FD_ZERO(&rfds);
FD_SET(xs_fileno(xsh), &rfds);
rc = select(nfds, &rfds, NULL, NULL, &tv);
int libxl_wait_for_device_model(libxl_ctx *ctx,
uint32_t domid, char *state,
int (*check_callback)(libxl_ctx *ctx,
+ uint32_t domid,
+ const char *state,
void *userdata),
void *check_callback_userdata);
int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state);
return 0;
}
+static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void *priv)
+{
+ char *orig_state = priv;
+
+ if ( !strcmp(state, "pci-insert-failed") )
+ return -1;
+ if ( !strcmp(state, "pci-inserted") )
+ return 0;
+ if ( !strcmp(state, orig_state) )
+ return 1;
+
+ return 1;
+}
+
static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
{
char *path;
pcidev->bus, pcidev->dev, pcidev->func);
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid);
xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins"));
- if (libxl_wait_for_device_model(ctx, domid, "pci-inserted", NULL, NULL) < 0)
- XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time");
+ rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, state);
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid);
vdevfn = libxl_xs_read(ctx, XBT_NULL, path);
- sscanf(vdevfn + 2, "%x", &pcidev->vdevfn);
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid);
+ if ( rc < 0 )
+ XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", vdevfn);
+ else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 )
+ rc = -1;
xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
+ if ( rc )
+ return ERROR_FAIL;
} else {
char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
pcidev->bus, pcidev->dev, pcidev->func);